﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nature
{
    public enum TemperatureChangeType
    {
        AtConstantPressure,
        AtConstantVolume,
        WithIsentropicCompression,
        WithShockCompression
    }

    public enum PressureChangeType
    {
        AtConstantTemperature,
        AtConstantVolume,
        WithIsentropicCompression,
        WithShockCompression
    }

    public enum DensityChangeType
    {
        AtConstantTemperature,
        AtConstantPressure,
        WithIsentropicCompression,
        WithShockCompression
    }

    public partial class IdealGasMixture
    {
        StateChangeCategory EvaluateTPChangeCategory(double t, double p)
        {
            StateChangeCategory category = StateChangeCategory.None;
            if (false == m_temperature.UpToDate || m_temperature.Value != t)
            {
                category |= StateChangeCategory.Temperature;
            }
            if (false == m_pressure.UpToDate || m_pressure.Value != t)
            {
                category |= StateChangeCategory.Pressure;
            }
            return category;
        }

        public void UpdateTemperature(double t, TemperatureChangeType changeType)
        {
            switch (changeType)
            {
                case( TemperatureChangeType.AtConstantPressure):
                    double p = m_pressure.Value;
                    DropState(StateChangeCategory.Temperature);
                    m_temperature.Value = t;
                    m_pressure.Value = p;
                    m_molarDensity.Value = p / t / Constants.Rgas;
                    break;
                default:
                    throw new NotImplementedException();
            }            
        }

        public void UpdatePressure(double p, PressureChangeType changeType)
        {
            throw new NotImplementedException();
        }

        public void UpdateDensity(double p, DensityChangeType changeType)
        {
            throw new NotImplementedException();
        }

        public void IncrementTPX(double t, double p, ReadOnlyArray<double> x)
        {
            throw new NotImplementedException();
        }
      

        public void IncrementTPY(double t, double p, ReadOnlyArray<double> y)
        {
            throw new NotImplementedException();
        }

        public void Update(IMixtureDefinition mixtureDefinition)
        {
            DropState(StateChangeCategory.Temperature | StateChangeCategory.Pressure | StateChangeCategory.Composition);
            m_temperature.Value = mixtureDefinition.Temperature;
            m_pressure.Value = mixtureDefinition.Pressure;
            m_molarDensity.Value = m_pressure.Value / m_temperature.Value / Constants.Rgas;
            double[] x = new double[Nsp];
            for (int jsp = 0; jsp < mixtureDefinition.X.Length; ++jsp)
            {
                int isp = Model.GetSpeciesIndex( mixtureDefinition.SpeciesIDs[jsp]);
                x[isp] = mixtureDefinition.X[jsp];
            }
            m_speciesMoleFractions.Assign(x);
        }

        public void UpdateTPX(double t, double p, ReadOnlyArray<double> x)
        {
            StateChangeCategory category = EvaluateTPChangeCategory(t, p) | StateChangeCategory.Composition;
            DropState(category);
            m_temperature.Value = t;
            m_pressure.Value = p;
            m_molarDensity.Value = p / t / Constants.Rgas;
            m_speciesMoleFractions.Assign(x.Data);
            m_speciesMassFractions.Update = calc_yk_from_xk;
            m_speciesMolarConcentrations.Update = __calc_ck_from_xk;
        }

        public void UpdateTPY(double t, double p, ReadOnlyArray<double> y)
        {
            StateChangeCategory category = EvaluateTPChangeCategory(t, p) | StateChangeCategory.Composition;
            DropState(category);
            m_temperature.Value = t;
            m_pressure.Value = p;
            m_molarDensity.Value = p / t / Constants.Rgas;
            m_speciesMassFractions.Assign(y.Data);
            m_speciesMassFractions.Update = calc_yk_from_xk;
            m_speciesMolarConcentrations.Update = __calc_ck_from_xk;
        }

    }

    
}
